package com.yjk1.example.myFirstSofawebBoot.framework;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yujiakui
 * @version 1.0
 * Email: jkyu@haiyi-info.com
 * date: 2018/11/14 下午9:41
 * description：框架对应的classLoader
 **/
public class DynamicFrameworkClassLoader extends URLClassLoader {

    /**
     * logger
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(DynamicFrameworkClassLoader.class);

    /**
     * 对应的动态加载jar classloader列表
     */
    private Map<String,ClassLoader> dynamicJarClassLoaderMap = new HashMap<>();

    public DynamicFrameworkClassLoader(ClassLoader parentClassLoader) {
        this(new URL[]{}, parentClassLoader);
    }

    public DynamicFrameworkClassLoader(){
        this(new URL[]{}, null);
    }

    /**
     * 构造函数
     * @param urls
     * @param parentClassLoader
     */
    public DynamicFrameworkClassLoader(URL[] urls,ClassLoader parentClassLoader){
        super(urls, null == parentClassLoader ?
                Thread.currentThread().getContextClassLoader(): parentClassLoader);
    }

    public Map<String, ClassLoader> getDynamicJarClassLoaderMap() {
        return dynamicJarClassLoaderMap;
    }

    public void setDynamicJarClassLoaderMap(Map<String, ClassLoader> dynamicJarClassLoaderMap) {
        this.dynamicJarClassLoaderMap = dynamicJarClassLoaderMap;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        if (StringUtils.isEmpty(name)) {
            return null;
        }

        Class<?> clazz = findLoadedClass(name);

        // try to load from parent
        try {
            System.out.println("superType----->"+super.getClass().getName());
            return super.loadClass(name);
        } catch (ClassNotFoundException e) {
            // try next step
        }

        // nope, try to load locally
        try {
            clazz = findClass(name);
            LOGGER.info("Found class '{}' in plugin classpath", name);
            return clazz;
        } catch (ClassNotFoundException e) {
            // try next step
        }

        if (null == clazz){
            for(ClassLoader classLoader: dynamicJarClassLoaderMap.values()){
                try {
                    clazz =  classLoader.loadClass(name);
                    if (null != clazz){
                        return clazz;
                    }
                } catch (ClassNotFoundException e) {
                    // ignore
                }
            }
            LOGGER.error("name={}对应的classLoader={}加载不到",name,dynamicJarClassLoaderMap.keySet());
        }

        return clazz;
    }


}
